//#pragma once

#ifndef __STRING_H__
#define __STRING_H__

#include <string.h>
#include <assert.h>
#include <iostream>
namespace dew
{
    class String
    {
    public:
        String(const char* str = "");
        String(size_t n,char ch);
        
        String(const String& s);
        String& operator=(String s);
        ~String();

        //迭代器相关操作
        typedef char* iterator;
        typedef const char* const_iterator;
        iterator begin() { return _str; }
        iterator end() { return _str + _size; }
        const_iterator begin() const { return _str; }
        const_iterator end() const { return _str + _size; }

        //string类对象的容量操作
        size_t size() const { return _size; }
        size_t capacity() const { return _capacity; }
        bool empty() const { return _size == 0; }
        void reserve(size_t n);
        void resize(size_t n,char ch = '\0');

        //string类对象的访问及遍历操作
        char& operator[](size_t pos) 
        {
            assert(pos < _size); 
            return _str[pos]; 
        }

        const char& operator[](size_t pos) const
        {
            assert(pos < _size); 
            return _str[pos]; 
        }

        char& at(size_t pos) 
        {
            assert(pos < _size); 
            return _str[pos]; 
        }

        const char& at(size_t pos) const
        {
            assert(pos < _size); 
            return _str[pos]; 
        }

        //string类对象的修改操作
        void push_back(char c);
        void append(const char* str);
        String& operator+=(char c);
        String& operator+=(const char* str);
        String substr(size_t pos,size_t len = npos);


        void clear() 
        {
            _str[0] = '\0';
            _size = 0;
        }

        void swap(String& s);

        const char* c_str() const { return _str; }

        const static size_t npos = -1;
    private:
        char* _str;
        size_t _size = 0;
        size_t _capacity = 0;
    };

    String::String(const char* str)
    {
        int len = strlen(str);
        _str = new char[len + 1];
        strcpy(_str,str);
        _size = len;
        _capacity = len;
    }

    String::String(const String& s): _str(nullptr),_size(0),_capacity(0)
    {
        String temp(s.c_str());
        std::swap(_str,temp._str);
        std::swap(_size,temp._size);
        std::swap(_capacity,temp._capacity);
    }

    String& String::operator=(String s)
    {
        swap(s);
        return *this;
    }

    void String::swap(String& s)
    {
        std::swap(_str,s._str);
        std::swap(_size,s._size);
        std::swap(_capacity,s._capacity);
    }

    String::String(size_t n,char ch) : _str(nullptr),_size(0),_capacity(0)
    {
        // _str = nullptr;
        // _size = 0;
        // _capacity = 0;
        resize(n,ch);
    }

    String::~String()
    {
        delete[] _str;
        _size = 0;
        _capacity = 0;
    }

    void String::reserve(size_t n)
    {
        if(n > _capacity)
        {
            char * newstr = new char[n + 1];
            _capacity = n;
            if(_str != nullptr)
                strcpy(newstr,_str);

            delete[] _str;
            _str = newstr;
        }
    }


    void String::resize(size_t n,char ch)
    {
        reserve(n);
        for(int i = _size; i < _capacity; i++)
        {
            _str[i] = ch;
            _size++;
        }
        _str[_capacity] = '\0';
    }

    void String::push_back(char c)
    {
        if(_size == _capacity)//需要扩容
        {
            size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
            reserve(newcapacity);
        }
        _str[_size] = c;
        _size++;
        _str[_size] = '\0';
    }

    void String::append(const char* str)
    {
        size_t len = strlen(str);
        if(len + _size >= _capacity) //需要扩容
        {
            size_t newcapacity = len + _size;
            reserve(newcapacity);
        }
        strcpy(_str + _size,str);
        _size = len + _size;
    }

    String& String::operator+=(char c)
    {
        push_back(c);
        return *this;
    }

    String& String::operator+=(const char* str)
    {
        append(str);
        return *this;
    }

    String String::substr(size_t pos,size_t len)
    {
        assert(pos < _size);
        if(pos + len >= _size || len == npos)
        {
            String ret(_str + pos);//直接构造一个返回
            return ret;
        }
        else
        {
            String ret;
            while(len)
            {
                ret += _str[pos];
                pos++;
                len--;
            }
            return ret;
        }
    }

    std::ostream& operator<<(std::ostream& out,String& s)
    {
        out << s.c_str();
        return out;
    }

    std::istream& operator>>(std::istream& in,String& s)
    {
        char ch = '\0';
        while(ch != '\n' && ch != ' ' && ch != EOF)
        {
            ch = getchar();
            s+=ch;
        }
        return in;
    }

}




#endif


